package com.ironone.streaming.application;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.URL;
import java.util.Locale;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.FontMetricsInt;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.os.Bundle;
import android.util.DisplayMetrics;
import com.facebook.HttpMethod;
import com.facebook.Request;
import com.facebook.Response;
import com.facebook.Response.PagingDirection;
import com.facebook.Session;
import com.facebook.model.GraphObject;

public class MainApplication extends Application {

	static String FILENAME = "formObject.ssm";
	public static int ANIME_DURATION = 500;
	public static int ANIME_DURATION_POWBY = 3000;

	@Override
	public void onCreate() {
		super.onCreate();

		// Clear garbaged fo and creates a fresh one
		if(FormObject.getInstanceOneTime() != null){
			FormObject.setInstanceOneTime(null);
		}

		FormObject.getInstance();
		getSavedFormObject(getApplicationContext());		
	}

	public static synchronized void foSaveChanges(Context context){
		try {
			if(context == null)
				return;
			
			FileOutputStream fos = context.openFileOutput(FILENAME, Context.MODE_PRIVATE);
			ObjectOutputStream out = new ObjectOutputStream(fos);
			out.writeObject(FormObject.getInstance());
			out.close();		
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private synchronized void getSavedFormObject(Context context){
		try {
			FileInputStream fis = context.openFileInput(FILENAME);
			ObjectInputStream in = new ObjectInputStream(fis);
			FormObject fo = (FormObject) in.readObject();

			// Set the fo's necessary properties to FormObject.getInstance() object here 
			FormObject.getInstance().setAccessToken(fo.getAccessToken());
			FormObject.getInstance().setDataVersion(fo.getDataVersion());
			FormObject.getInstance().setUpdateArray(fo.getUpdateArray());
			FormObject.getInstance().setTNLId(fo.getTNLId());

			FormObject.getInstance().setFbName(fo.getFbName());
			FormObject.getInstance().setFbEmail(fo.getFbEmail());
			FormObject.getInstance().setFbBirthday(fo.getFbBirthday());
			FormObject.getInstance().setFbLocation(fo.getFbLocation());
			FormObject.getInstance().setFbGender(fo.getFbGender());
			FormObject.getInstance().setFbMusicLiked(fo.getFbMusicLiked());
			FormObject.getInstance().setFbUsername(fo.getFbUsername());
			FormObject.getInstance().setFbUserId(fo.getFbUserId());
			FormObject.getInstance().setFbProfilePicture(fo.getFbProfilePicture());

			FormObject.getInstance().setSDStream(fo.getSDStream());
			FormObject.getInstance().setHDStream(fo.getHDStream());

			FormObject.getInstance().setShowsData(fo.getShowsData());
			FormObject.getInstance().setEventsData(fo.getEventsData());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}


	/* Common */
	public static void getScreenDimensions(Activity act){
		try {
			DisplayMetrics displaymetrics = new DisplayMetrics();
			act.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);

			FormObject.getInstance().setScreenWidth(displaymetrics.widthPixels);
			FormObject.getInstance().setScreenHeight(displaymetrics.heightPixels);
		} catch (Exception e) {
		}
	}

	static float ifErrorDefaultSize = 15;
	public static void getScreenTextSize(Activity act){
		try {
			int screenWidth = FormObject.getInstance().getScreenWidth();
			int screenHeight = FormObject.getInstance().getScreenHeight();

			float val = SetTextSize("text", (int)(screenWidth * 0.06), (int)(screenHeight * 0.09));

			DisplayMetrics metrics = new DisplayMetrics();
			act.getWindowManager().getDefaultDisplay().getMetrics(metrics);
			int density = (int)metrics.density;
			
			if(density == 1 && val > 20)
				val = 20;

			if(density == 2 && val > 17)
				val = 17;

			if(density >= 3 && val > 15)
				val = 15;

			FormObject.getInstance().setTextSize(val);
		} catch (Exception e) {
			FormObject.getInstance().setTextSize(ifErrorDefaultSize);
		}
	}

	private static float SetTextSize(String text, int width, int height) {
		try {
			Paint paint = new Paint();
			float textWidth = paint.measureText(text);
			float textSize = (int) ((width / textWidth) * paint.getTextSize());
			paint.setTextSize(textSize);

			textWidth = paint.measureText(text);
			textSize = (int) ((width / textWidth) * paint.getTextSize());

			// Re-measure with font size near our desired result
			paint.setTextSize(textSize);

			// Check height constraints
			FontMetricsInt metrics = paint.getFontMetricsInt();
			float textHeight = metrics.descent - metrics.ascent;
			if (textHeight > height)
			{
				textSize = (int) (textSize * (height / textHeight));
				paint.setTextSize(textSize);
			}
			return textSize;
		} catch (Exception e) {
			return ifErrorDefaultSize;
		}
	}

	public static Bitmap getRoundedRectBitmap(Activity act, Bitmap bitmap, boolean needResize) {
		Bitmap result = null;
		Bitmap resizedbitmap = null;
		try {

			int ss = FormObject.getInstance().getScreenWidth();
			ss = (int)(ss / 2.6);
			int pixels = (int) ((ss * 0.6));

			if(needResize){
				resizedbitmap = Bitmap.createScaledBitmap(bitmap, pixels, pixels, true);
			}

			result = Bitmap.createBitmap(pixels, pixels, Bitmap.Config.ARGB_8888);
			Canvas canvas = new Canvas(result);

			int color = 0xff424242;
			Paint paint = new Paint();
			Rect rect = new Rect(0, 0, pixels, pixels);

			paint.setAntiAlias(true);
			canvas.drawARGB(0, 0, 0, 0);
			paint.setColor(color);
			int r = (int)(pixels / 2);
			canvas.drawCircle(r, r, r, paint);
			paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));

			if(needResize)
				canvas.drawBitmap(resizedbitmap, rect, rect, paint);
			else
				canvas.drawBitmap(bitmap, rect, rect, paint);

		} catch (Exception o) {
			return null;
		}
		return result;
	}

	public static void getFacebookProfileData(Activity act){
		try {
			if(Session.getActiveSession().isOpened()){
				int ss = FormObject.getInstance().getScreenWidth();
				ss = (int)(ss / 2.6);
				int profilePicWidth = (int)(ss * 0.6);

				Bundle params = new Bundle();
				params.putBoolean("redirect", false);
				params.putString("height", profilePicWidth + "");
				params.putString("type", "normal");
				params.putString("width", profilePicWidth + "");

				Request request0 = new Request(Session.getActiveSession(), "/me/picture", params, HttpMethod.GET); 
				Response response0 = request0.executeAndWait();

				if(response0.getError() != null){
					FormObject.getInstance().setFbProfilePicture(null);
					return;
				}

				// Get the picture
				GraphObject graphObject = response0.getGraphObject();
				JSONObject jsonObject = graphObject.getInnerJSONObject();
				URL fbProfilePicURL = new URL(jsonObject.getJSONObject("data").getString("url"));
				Bitmap bitmap = BitmapFactory.decodeStream(fbProfilePicURL.openConnection().getInputStream());

				FormObject.getInstance().setFbProfilePicture(getBitmapToByteArr(bitmap));
				MainApplication.foSaveChanges(act);


				// Get the name 
				Request request1 = new Request(Session.getActiveSession(), "/me/", null, HttpMethod.GET); 
				response0 = request1.executeAndWait();

				if(response0.getError() != null){
					return;
				}

				GraphObject go  = response0.getGraphObject();
				JSONObject jso = go.getInnerJSONObject();
				try {
					FormObject.getInstance().setFbName(jso.getString("name"));
					
					FormObject.getInstance().setFbUsername(jso.getString("username"));					
					FormObject.getInstance().setFbUserId(jso.getString("id"));
					FormObject.getInstance().setFbEmail(jso.getString("email"));
					FormObject.getInstance().setFbBirthday(jso.getString("birthday"));
					FormObject.getInstance().setFbLocation(jso.getString("location"));
					FormObject.getInstance().setFbGender(jso.getString("gender"));
					
					MainApplication.foSaveChanges(act);
					
					/*Request request2 = new Request(Session.getActiveSession(), "/me/music", null, HttpMethod.GET); 
					Response response1 = request2.executeAndWait();

					if(response1.getError() == null){
						GraphObject go1  = response1.getGraphObject();
						JSONObject jso1 = go1.getInnerJSONObject();
						try {
							FormObject.getInstance().setFbMusicLiked(jso1.getJSONArray("data").toString());
							MainApplication.foSaveChanges(act);
						} catch (JSONException e) {
							e.printStackTrace();
						}						
					}*/
					
					StringBuilder sb = new StringBuilder();
					boolean proceed = true;
					String reqURL = "/me/music";

					Request request = new Request(Session.getActiveSession(), reqURL, null, HttpMethod.GET); 
					Response response = request.executeAndWait();
					try {
						JSONArray dataArr = response.getGraphObject().getInnerJSONObject().getJSONArray("data");
						if(dataArr.length() <= 0) proceed = false;
						
						for (int i = 0; i < dataArr.length(); i++) {
							JSONObject json_data = dataArr.getJSONObject(i);
							
							//if (json_data.getString("category").toLowerCase(Locale.ENGLISH).startsWith("radio station")
								//	|| json_data.getString("category").toLowerCase(Locale.ENGLISH).startsWith("musician"))
								sb.append(json_data.getString("name") + "#@#");
						}
					} catch (JSONException e) {
						proceed = false;
					}
					
					while (proceed) {				
							Request nextPageRequest = response.getRequestForPagedResults(PagingDirection.NEXT);
							response = nextPageRequest.executeAndWait();
							
							try {
								JSONArray dataArr = response.getGraphObject().getInnerJSONObject().getJSONArray("data");
								if(dataArr.length() <= 0) proceed = false;
								
								for (int i = 0; i < dataArr.length(); i++) {
									JSONObject json_data = dataArr.getJSONObject(i);
									
									//if (json_data.getString("category").toLowerCase(Locale.ENGLISH).startsWith("radio")
										//	|| json_data.getString("category").toLowerCase(Locale.ENGLISH).startsWith("musician"))
										sb.append(json_data.getString("name") + "#@#");
								}
							} catch (JSONException e) {
								proceed = false;
							}
						}
							
					FormObject.getInstance().setFbMusicLiked(sb.toString());
					MainApplication.foSaveChanges(act);
				}catch(Exception e){						
				}
			}
		} catch (Exception e) {
			FormObject.getInstance().setFbProfilePicture(null);
		}
	}

	public static int getDayIndex(){
		try {
			String dayName = FormObject.getInstance().getDay().trim().toLowerCase(Locale.ENGLISH);
			if(dayName.equals("monday"))
				return 0;
			if(dayName.equals("tuesday"))
				return 1;
			if(dayName.equals("wednesday"))
				return 2;
			if(dayName.equals("thursday"))
				return 3;
			if(dayName.equals("friday"))
				return 4;
			if(dayName.equals("saturday"))
				return 5;
			if(dayName.equals("sunday"))
				return 6;
			
			return 0;  //If fails
		} catch (Exception e) {
			return 0;  //If fails
		}
	}

	public static byte[] getBitmapToByteArr(Bitmap data){
		try {
			if(data == null) return null;
			ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
            boolean success = data.compress(Bitmap.CompressFormat.PNG, 100, byteStream);
            if(success){
                return byteStream.toByteArray();
            }
            return null;
		} catch (Exception e) {
			return null;
		}
	}
	
	public static Bitmap getByteArrToBitmap(byte[] data){
		try {
			if(data != null && data.length > 0){
	            return BitmapFactory.decodeByteArray(data, 0, data.length);
	        }
			return null;
		} catch (Exception e) {
			return null;
		}
	}
}